/** @jsxImportSource @emotion/react */
//import { jsx, css } from "@emotion/react";
import * as React from "react";
import {
    Navbar,
    Toolbar,
    Text,
    Button,
    IconButton,
    MenuList,
    MenuItem,
    useTheme,
    useToast,
    LayerLoading,
    Container,
    IconMoreVertical,
    PanelEnlargeCtx,
    TwoHalfRightPanel,
    IconArrowLeft,
    IconArrowRight,
    IconPackage,
    IconRefButton,
    IconCloud,
    VerticalMenu,
    DdMenuItem,
    IconCheckSquare,
    DdMenu, IconMenu, InputPure, IconX
} from "customize-easy-ui-component";
import { Link as RouterLink } from "../routing/Link";
//import {Helmet} from "react-helmet";
//import { Link as RouterLink, Route, Switch, useLocation, useRoute } from "wouter";
//import { ContainLine, TransparentInput } from "../comp/base";
//import {useDeviceDetail, useRemoveEQP} from "./db";
//import { AddToTask } from "./task/AddToTask";
//import { DeviceDetail } from "./DeviceDetail";
import { ComposeDevice } from "./ComposeDevice";
//graphql不能用react-relay/hooks的。报错 Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify
import {PreloadedQuery, usePreloadedQuery} from "react-relay/hooks";
import {DetailedGuideQuery} from "./__generated__/DetailedGuideQuery.graphql";
import {DeviceDetail} from "./DeviceDetail";
import {Fragment, useContext} from "react";
import RoutingContext from "../routing/RoutingContext";
import useConfirmTaskFeeMutation from "../task/fee/useConfirmTaskFeeMutation";
import useAddDeviceToTaskMutation from "./useAddDeviceToTaskMutation";
import {useDeviceMultiSelect} from "./hook/useDeviceMultiSelect";
import {IEqpEntity} from "../comp/ChooseEqps";
import useSessionStorageState from "use-session-storage-state";
import {SuffixRefInput} from "customize-easy-ui-component/esm/Form";
// import {useUid} from "customize-easy-ui-component/esm/Hooks/use-uid";

const graphql = require("babel-plugin-relay/macro");    //必须这样!编译器解析graphql文本代码。


interface DetailedGuideProps {
    id?: string;   　//来自上级<Route path={"/device/:id/"} component={} />给的:id。
    prepared: {
        eqpQuery: PreloadedQuery<DetailedGuideQuery>;
    }
    children: React.ReactNode;
    routeData: any;
}
//右半边页面 把该设备加入刚才选定那条任务中。
export default function DetailedGuide(props: DetailedGuideProps) {
    const theme = useTheme();
    const toast = useToast();
   // const [, setLocation] = useLocation();
   // const [match, params] = useRoute("/device/:id/:rest*");
   // let id =(match && params.id);
   // if(id==='new')
    //const id=undefined;
    const data = usePreloadedQuery<DetailedGuideQuery>(
        graphql`
            query DetailedGuideQuery($id: ID! ) {
                getDeviceSelf(id: $id) {
                    id,version,oid,cod,type,sort,vart,subv,svp,pa,cpa,vital,titl,lpho,
                    plat,used,expire,move,money,impt,model,fno,plno,insd,ocat,
                    address,lon,lat,plcls,dense,seimp,vlg{id,name},
                    ad{id,prefix,name,country{id},province{id},city{id},county{id},town{id}},
                    mkd,ust,uscd,cert,cerd,reg,sno,rcod,rnam,regd,cand,crDate,
                    makeu{id company{id name} person{id name}},
                    regu{id company{id name}}, owner{id company{id name} person{id name}},
                    remu{id company{id name} person{id name}}, repu{id company{id name} person{id name}},
                    insu{id company{id name} person{id name}}, mtu{id company{id name}},
                    svu{id company{id name}}, ispu{id company{id name}},ispud{id name},
                    useu{id company{id name no linkMen phone address} person{id name no phone address}},
                    usud{id name linkMen phone address branch}, nxtd1,nxtd2,
                    isp1{id no ispDate bsType conclusion bus{id task{id date origd}} report{id,stm{id,sta}}},
                    isp2{id no ispDate bsType conclusion bus{id task{id date origd}} report{id,stm{id,sta}}},
                    ... on Elevator {  
                        flo,spec,nnor,oldb,vl,hlf,lesc,wesc,cpm,tm,mtm,buff,
                        rtl,aap,prot,doop,limm,opm,lbkd,nbkd
                    }
                    ... on Boiler {
                        wall,power,form,fuel,pres,bmod,asemb
                    }
                    ... on Crane {
                        hlf,hlfm,nnor,vls,flo,tm,cpm,opm,rtlf,cap,rvl,mvl,cvl,scv,
                        lmv,rtv,luff,ns,pnum,rang,span,two,twoc,grab,suck,cotr,
                        walk,mom,whole,tno,cpi,pcs,pcw,miot,luf,jobl,highs,part,
                        occa,metl,level,auxh,wjib,
                    }
                    ... on Vessel {
                        vol,prs,pnum,highs,weig,rtlf,fulw,mdi,jakm,form,insul,mont,
                    }
                    ... on FactoryVehicle {
                        rtlf,mtm,pow
                    }
                    ... on Amusement {
                        level,mbig,leng,high,hlf,pnum,vl,sdia,grad,angl
                    }
                    ... on Pipeline {
                        level,matr,mdi,prs,temp,numCell
                    }
                    __typename
                }
            }
        `,
        props.prepared.eqpQuery,
    );
    //【最早】设备台账最早的数据从这里开启，graphQL/Relay获得：
    const { getDeviceSelf, }=data;
    //graphQL接口转换js对象自动塞给接口String得到的不正常也不是json的字符串，只能采用JSON.stringify()不可缺少的；
    const  svp = JSON.parse(getDeviceSelf?.svp || '{}');
    const  pa = JSON.parse(getDeviceSelf?.pa || '{}');
    //提前到这,距离graphQL接口最接近的地方：进行转换svp和pa的动作。
    const eqp ={ ...getDeviceSelf! , svp ,pa };
    const {call:addDeviceToTaskFunc,doing:addting,called:addted, result:addtrs}= useAddDeviceToTaskMutation();


  async function updateRecipe(id: string) {
    try {
    //  await updateFunc();
    } catch (err: any) {
      toast({
        title: "后端报错",
        subtitle: err.message,
        intent: "error"
      });
      return;
    }
    toast({
      title: "返回了",
      subtitle: '作废 ID＝'+id,
      intent: "info"
    });
  }
  //集成 设备挑选的 功能，避免需要再造孤立的模态状态对话框也即设备选择对话框组件。
    const { history } = useContext(RoutingContext);
    const {save, field, reurl, p1field, multi}= window.history.state?.state??{};      //通用伪对话框传递格式
    console.log("返回刚才编辑器页面 frm-save=", save,"reurl=",reurl);
    //一般编辑器页面点击转去伪对话框路由页面，实际都是针对某一个特定属性字段filed={}的选定设置。 上面reurl参数就是保存了返回的URL;
    //.svp{} .pa{} 这样子是嵌套的对象里面的待设置的属性字段如何是好啊：修改嵌套第二层的字段?
    const [dxDevs, setDxDevs, { isPersistent,removeItem  }] = useSessionStorageState('设备多选集', {
        defaultValue: [] as any[]
    });
 //【冲突】设备台账既可以跳去选择单位后返回编辑，也可能新任务页面到这里挑选设备待返回。只好用reurl作为区分条件！
    if(save && field) {          //修改成当前选择的单位。 field是原始编辑页面的保存属性字段名。
        console.log("伪对话—台账改单位也来这：", window.history.state?.state);
        if(reurl) {
            if(multi){      //？？不应该有这个？##
                if (p1field) save[p1field][field] = dxDevs;
                else save[field] = dxDevs;
            }else {
                if (p1field) save[p1field][field] = {id: eqp?.id, name: eqp?.cod};      //最多2层的编辑的目标对象属性字段。
                else save[field] = {id: eqp?.id, name: eqp?.cod};
            }
  //【嵌套地狱】这里修改save[field]也会导致window.history.state?.state同步被修改了问题！某页面【选择设备】和设备再去单位选择冲突，跳2次对话框?
        }
    }
    const taskCurSel=sessionStorage['当前任务'] && JSON.parse(sessionStorage['当前任务']);     //&&JSON.parse(sessionStorage['单位选择']);
 //const id=useUid();【路由问题！】点击左半边的设备列表，切换右边的设备时这里的useUid(++)竟然保持不变。必须在底下加上key={props.routeData.params.id!}才能保证完全能更新页面显示。
    const handleSelect = React.useCallback(() => {
        if(save && field) {
            if(reurl) {
                if(multi){
                    if (p1field) save[p1field][field] = dxDevs;
                    else save[field] = dxDevs;
                }else {
                    if (p1field) save[p1field][field] = {id: eqp?.id, name: eqp?.cod};
                    else save[field] = {id: eqp?.id, name: eqp?.cod};
                }
            }
        }
    }, [dxDevs,save, field,reurl,multi,p1field,eqp]);
    const handleReset = React.useCallback(() => {
        setDxDevs([]);
    }, [setDxDevs]);
    const inDxDevs= dxDevs?.some((device: { id: string; }) => device.id===eqp.id);
    const {view: selectDevsDialog, open, setOpen}= useDeviceMultiSelect({dxDevs, setDxDevs,
               onReset: handleReset,  });

  return (
    <TwoHalfRightPanel   key={props.routeData.params.id!}
        title={ reurl?
            <Button size="lg" intent="primary" variant="ghost" iconAfter={<IconCloud />}
                    css={{ whiteSpace: 'unset' }}
                    onPress={ async () => {
                        handleSelect();
                        console.log("点反汇编及save=", save,dxDevs);
                        await history.push(reurl, {save,field,p1field,multi});
                    } }
            >{multi? '挑完多选集' : '选定这个'}，返回刚才编辑器页面
            </Button>
            :
            `看${eqp.cod || eqp.oid}`
        }
        back={
            <IconButton    icon={<IconArrowLeft />}
                         variant="ghost"
                         label="后退"
                         size="md"
                         css={{
                             marginRight: theme.spaces.sm,
                             [theme.mediaQueries.md]: {
                                 display: "none"
                             }
                         }}
                         onPress={ async () => { await history.push("/device", {save,field,reurl,p1field,multi});} }
            />
        }
        menu={
            <VerticalMenu>
                <DdMenuItem label="生成新任务"
                            onClick={(e) => {
                                //   setLocation("/device/"+id+"/addTask", { replace: false });
                            }}/>
                {taskCurSel && (
                        <DdMenuItem label="加入刚选择的任务(另外派工)"
                                    onClick={async (e) => {
                                       await addDeviceToTaskFunc(taskCurSel, eqp?.id);
                                    }}/>
                ) }
                {taskCurSel && (
                        <DdMenuItem label="当前任务是"
                                    onClick={async(e) => {
                                        history.push(`/task/${taskCurSel}`);
                                    }}/>
                ) }
                <DdMenuItem label="其它功能"
                            onClick={(e) => {
                            }}/>
                {/*
                  <MenuItem onPress={() => updateRecipe(id) }>法定设备导入后的拆除报废</MenuItem>
                  <MenuItem onPress={() => removeEqpFunc() }>(委托)设备不再维护时删除</MenuItem>
                  <MenuItem onPress={() => refetch( {} )}>刷新获最新数据</MenuItem>
                    */}
            </VerticalMenu>
            }
    >

      <DeviceDetail id={props.routeData.params.id!} eqp={eqp}/>
      <div css={{ marginTop: theme.spaces.sm }}>
        <RouterLink href={`/device/`}>
          <Button
            size="lg" noBind
            intent="primary"
            iconAfter={<IconArrowRight />}
          >
            其他3功能
          </Button>
        </RouterLink>
      </div>
        { reurl &&
            <Button size="lg" intent="primary" variant="ghost" iconAfter={<IconCloud />}
                onPress={ async () => {
                    if(save && field) {          //修改成当前选择的单位。 field是原始编辑页面的保存属性字段名。
                        console.log("伪对话返回编辑器去：", window.history.state?.state);
                        if(reurl) {
                            if(multi){
                                //onPress按钮里面看见dxDevs却不是最新的！
                                if (p1field) save[p1field][field] = dxDevs;
                                else save[field] = dxDevs;
                            }else {
                                if (p1field) save[p1field][field] = {id: eqp?.id, name: eqp?.cod};      //最多2层的编辑的目标对象属性字段。
                                else save[field] = {id: eqp?.id, name: eqp?.cod};
                            }
                        }
                    }
                    await history.push(reurl, {save,field,multi});
                } }
            >{multi? '挑完多选集' : '选定这个'}，返回刚才编辑器页面
            </Button>
        }

        <div css={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-evenly',
        }}>
            <IconButton
                onClick={() => 0}
                variant="ghost"
                label="多选或取消"
                icon={ <IconCheckSquare /> }
            />
            <DdMenu label="多选" icon={<Button size="sm">多选</Button>} >
                <DdMenuItem label={inDxDevs? "移出多选集" : "加入多选集" }
                            onClick={  () => {
                                //后端给的GlobalId的type不一致导致，一个设备有不同id的；
                                let newarr;
                                if (inDxDevs) {
                                    newarr= dxDevs.filter((device: { id: string; }) => device.id !== eqp.id);
                                } else {
                                    const one = {...eqp} as unknown as IEqpEntity;
                                    //dxDevs.push(one);   不能这么用啊！必须不可变量给setXXX(), 不能直接添加到dxDevs，否则后面的setDxDevs就没真的动作没变化？
                                    newarr= dxDevs? dxDevs.concat(one) : [one];
                                }
                                setDxDevs(newarr);
                                // sessionStorage['设备多选集'] =JSON.stringify(newarr);
                            } } />
                <DdMenuItem label={`当前多选集${dxDevs?.length || 0}个设备`}
                            onClick={  () => {
                                setOpen(true);
                                console.log("展示当前多选集=[",  dxDevs,  "] 几个=", dxDevs.length);
                            } } />
            </DdMenu>
            <DdMenu label="内菜单" tight={true}
                    icon={
                        <MenuItem variant="ghost"  component={"div"}>
                            <IconMenu />
                        </MenuItem>
                    }
            >
                <DdMenuItem label="当前任务是"
                            onClick={async(e) => {
                                // history.push(`/task/${taskCurSel}`);
                            }}/>
            </DdMenu>
            {selectDevsDialog}
        </div>

    </TwoHalfRightPanel>
  );
};



/*为了能立刻刷新操作反馈页面，引入三级路由，把数据获取放在了公共上级组件去，某页面操作的同时能更新查询另外页面显示立即反馈到。
function ThirdRouterContent({id, device}: ThirdRouterProps) {
    return (
        <React.Fragment>
            <Switch>
                <Route path={"/device/new"}>
                    <ComposeDevice  readOnly={false}/>
                </Route>
                <Route path={"/device/:id/addTask"}>
                    <AddToTask id={id} dt={device}/>
                </Route>
                <Route path={`/device/:id`}>
                    <DeviceDetail id={id} eqp={device}/>
                </Route>
                <Route path="/:rest*">没该URL内容</Route>
            </Switch>
        </React.Fragment>
    );
}*/
